iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

使用 Kotlin 快速開發 Web 程式 -- Vaadin系列 第 14

VoK 系統功能權責劃分 ( II ) - day14

  • 分享至 

  • xImage
  •  

限制可執行權限

VoK-Security 提供三個限定權限的 annotation

  • @AllowRoles - 須帶參數roles, 若未帶參數,則無任何使用者擁有進入此畫面權限
  • @AllowAll - 所有使用者皆有權限,無論有無登入
  • @AssowAllUsers - 所有已登入使用者皆有權限

根據昨天所設定的角色分配,分配新增/修改/刪除學生權限。

  1. 請打開 EditStudent.kt,在 class 前加上 annotation
@Route("edit-student", layout = MainLayout::class)
@AllowRoles("administrator")
class EditStudent : KComposite(), HasUrlParameter<Long> {
  1. 刪除學生寫在 AllStudentsView.kt 裡,但此畫面任一登入使用者皆有觀看權限,需要使用其他方法限制權限。
    if (Session.loginService.isUserInRole("administrator")) {
        addButtonColumn(VaadinIcon.TRASH, "delete") {
            confirmDialog(text = "是否確定刪除${it.name}的資料?") {
                it.delete()
                this.refresh()
            }
        }
    }

第一行,判斷登入使用者是否具有 administrator 權限

設定

加好角色限制annotation後,需要設定在UI跳轉到畫面前進行檢查。

設定已登入使用者資訊

Bootstrap.kt contextInitialized()方法加上

    VaadinOnKotlin.loggedInUserResolver = object : LoggedInUserResolver{
        override fun isLoggedIn(): Boolean = Session.loginService.isLoggedIn
        override fun getCurrentUserRoles(): Set<String> = Session.loginService.getCurrentUserRoles()
    }

啟動檢查機制

請開啟MainLayout.kt,在beforeEnter()方法加上檢查

    override fun beforeEnter(event: BeforeEnterEvent) {
        if (event.navigationTarget != LoginView::class.java && !Session.loginService.isLoggedIn){
            event.rerouteTo(LoginView::class.java)
        }else{
            VokSecurity.checkPermissionsOfView(event.navigationTarget)
        }
    }

MainLayout啟動檢查的方式僅適用layout為 MainLayout之畫面 @Route(path, layout = MainLayout::class)。倘若希望整個系統執行時,無論有無指定 layout 皆須事先判斷則採用註冊 Listener方法。

註冊Listener

  1. 實作Listner。請開新檔 SysInitListener.kt
package com.example.vok

import com.vaadin.flow.server.ServiceInitEvent
import com.vaadin.flow.server.VaadinServiceInitListener
import eu.vaadinonkotlin.vaadin10.Session
import eu.vaadinonkotlin.vaadin10.VokSecurity

class SysInitListener: VaadinServiceInitListener {
    override fun serviceInit(event: ServiceInitEvent) {
        event.source.addUIInitListener { uiInitEvent ->
            uiInitEvent.ui.addBeforeEnterListener { beforeEnterEvent ->
                if (!Session.loginService.isLoggedIn && beforeEnterEvent.navigationTarget != LoginView::class.java){
                    beforeEnterEvent.rerouteTo(LoginView::class.java)
                }else{
                    VokSecurity.checkPermissionsOfView(beforeEnterEvent.navigationTarget)
                }
            }
        }
    }
}
  1. 註冊Listener。Vaadin 是基於 Java Servlet 的框架,RequestHandlers、BootstrapListeners、DependencyFilters 都配置在 VaadinServiceInitListener。在 web/src/main/resource/META-INF/services/ 開啟新檔 com.vaadin.flow.server.VaadinServiceInitListener,寫入含 package的class name即可。
com.example.vok.SysInitListener

最後記得在每個畫面賦予適合權限,否則會出 AccessRejectedException


上一篇
VoK 系統功能權責劃分 ( I ) - day13
下一篇
VoK Grid 各種資料型態過濾器 - day15
系列文
使用 Kotlin 快速開發 Web 程式 -- Vaadin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言